﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using EnvDTE;
using System.IO;
using SPVisualDev.VSAddin.Dialogs;
using System.ServiceProcess;
using System.ServiceModel;
using SPVisualDev.VSAddin.Services;

namespace SPVisualDev.VSAddin
{
    public partial class SettingsPageRemote : UserControl, IDTToolsOptionsPage
    {
        internal const string C_PARAM_REMOTE_SERVER_USE = "RemoteServerUse";
        internal const string C_PARAM_REMOTE_SERVER_ADDRESS = "RemoteServer";
        internal const string C_PARAM_REMOTE_SERVER_PORT = "RemoteServerPort";
        internal const string C_PARAM_REMOTE_USE_DIFFERENT_CRED = "RemoteServerUseDifferentCred";
        internal const string C_PARAM_REMOTE_SERVER_USERNAME = "RemoteServerUserName";
        internal const string C_PARAM_REMOTE_SERVER_PASSWORD = "RemoteServerPassword";

        private DTE m_dte;

        public SettingsPageRemote()
        {
            InitializeComponent();
        }


        public void GetProperties(ref object PropertiesObject)
        {
        }

        public void OnAfterCreated(DTE DTEObject)
        {
            try
            {
                m_dte = DTEObject;
                
                InitValues();
            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        internal void SetDTE(DTE DTEObject)
        {
            m_dte = DTEObject;
        }

        internal void InitValues()
        {
            string value = Common.GetUserRegistryParam(C_PARAM_REMOTE_SERVER_USE, true);
            if (!string.IsNullOrEmpty(value))
            {
                this.RemoteServerUse = bool.Parse(value);
            }

            value = Common.GetUserRegistryParam(C_PARAM_REMOTE_SERVER_ADDRESS, true);
            if (string.IsNullOrEmpty(value))
                value = "localhost";

            txtRemoteServerAddress.Text = value;

            value = Common.GetUserRegistryParam(C_PARAM_REMOTE_SERVER_PORT, true);
            if (string.IsNullOrEmpty(value))
                value = Common.C_WCF_MAIN_SVC_PORT.ToString();

            txtRemoteServerPort.Text = value;


            value = Common.GetUserRegistryParam(C_PARAM_REMOTE_USE_DIFFERENT_CRED, true);
            if (!string.IsNullOrEmpty(value))
            {
                this.RemoteServerUseDifferentCred = bool.Parse(value);
            }

            if (this.RemoteServerUseDifferentCred)
            {
                try
                {
                    value = Common.GetUserRegistryParam(C_PARAM_REMOTE_SERVER_USERNAME, true);
                    if (!string.IsNullOrEmpty(value))
                        this.RemoteServerUserName = Common.DecryptUsingKeyContainer(value);

                    value = Common.GetUserRegistryParam(C_PARAM_REMOTE_SERVER_PASSWORD, true);
                    if (!string.IsNullOrEmpty(value))
                        this.RemoteServerPassword = Common.DecryptUsingKeyContainer(value);
                }
                catch (System.Security.Cryptography.CryptographicException)
                {
                    this.RemoteServerUserName = "";
                    this.RemoteServerPassword = "";
                    this.RemoteServerUseDifferentCred = false;
                }
            }
            else
            {
                this.RemoteServerUserName = "";
                this.RemoteServerPassword = "";
            }

            SetFieldVisibleStates();
        }

        internal void SetFieldVisibleStates()
        {
            chkUseDifferentCred_CheckedChanged(null, null);
            chkUseDifferentCred.CheckedChanged += new EventHandler(chkUseDifferentCred_CheckedChanged);

            chkUseRemoteServer_CheckedChanged(null, null);
            chkUseRemoteServer.CheckedChanged += new EventHandler(chkUseRemoteServer_CheckedChanged);
        }

        private void chkUseRemoteServer_CheckedChanged(object sender, EventArgs e)
        {
            if (!this.RemoteServerUse)
            {
                this.txtRemoteServerAddress.Enabled = false;
                this.txtRemoteServerPort.Enabled = false;
                this.txtPassword.Enabled = false;
                this.txtUser.Enabled = false;
                this.chkUseDifferentCred.Enabled = false;
                this.btnTestSettings.Enabled = false;
            }
            else
            {
                if (string.IsNullOrEmpty(this.txtRemoteServerPort.Text))
                {
                    this.txtRemoteServerPort.Text = Common.C_WCF_MAIN_SVC_PORT.ToString();
                }

                this.txtRemoteServerAddress.Enabled = true;
                this.txtRemoteServerPort.Enabled = true;
                this.txtPassword.Enabled = this.RemoteServerUseDifferentCred;
                this.txtUser.Enabled = this.RemoteServerUseDifferentCred;
                this.chkUseDifferentCred.Enabled = true;
                this.btnTestSettings.Enabled = true;
            }
        }

        private void chkUseDifferentCred_CheckedChanged(object sender, EventArgs e)
        {
            if (!this.RemoteServerUseDifferentCred)
            {
                this.RemoteServerUserName = string.Empty;
                this.RemoteServerPassword = string.Empty;

                this.txtUser.Enabled = false;
                this.txtPassword.Enabled = false;
            }
            else
            {
                this.txtUser.Enabled = true;
                this.txtPassword.Enabled = true;
            }
        }


        public void OnCancel()
        {
        }

        public void OnHelp()
        {
            throw new NotImplementedException();
        }

        public void OnOK()
        {
            try
            {
                if (this.RemoteServerUse && string.IsNullOrEmpty(this.RemoteServerAddress))
                {
                    throw new Exception("Invalid server adress");
                }

                if (this.RemoteServerUse && string.IsNullOrEmpty(this.RemoteServerPort))
                {
                    throw new Exception("Invalid server port");
                }

                Common.SetUserRegistryParam(C_PARAM_REMOTE_SERVER_USE, this.RemoteServerUse.ToString());
                Common.SetUserRegistryParam(C_PARAM_REMOTE_SERVER_ADDRESS, this.RemoteServerAddress);
                Common.SetUserRegistryParam(C_PARAM_REMOTE_SERVER_PORT, this.RemoteServerPort);
                Common.SetUserRegistryParam(C_PARAM_REMOTE_USE_DIFFERENT_CRED, this.RemoteServerUseDifferentCred.ToString());

                if (this.RemoteServerUseDifferentCred)
                {
                    Common.SetUserRegistryParam(C_PARAM_REMOTE_SERVER_USERNAME, Common.EncryptUsingKeyContainer(this.RemoteServerUserName));
                    Common.SetUserRegistryParam(C_PARAM_REMOTE_SERVER_PASSWORD, Common.EncryptUsingKeyContainer(this.RemoteServerPassword));
                }
                else
                {
                    Common.SetUserRegistryParam(C_PARAM_REMOTE_SERVER_USERNAME, "");
                    Common.SetUserRegistryParam(C_PARAM_REMOTE_SERVER_PASSWORD, "");
                }

                Connect connectClass = m_dte.AddIns.Item(typeof(Connect).FullName).Object as Connect;
                if (connectClass.SpecialSolution != null)
                {
                    List<SpecialProject> listOfProjects = connectClass.SpecialSolution.GetAllSpecialProjects();
                    foreach (SpecialProject p in listOfProjects)
                    {
                        p.ReloadServiceProxy();
                    }
                }
            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }


        public bool RemoteServerUse
        {
            get { return chkUseRemoteServer.Checked; }
            set { chkUseRemoteServer.Checked = value; }
        }

        public string RemoteServerAddress
        {
            get { return txtRemoteServerAddress.Text; }
            set { txtRemoteServerAddress.Text = value; }
        }

        public string RemoteServerPort
        {
            get { return txtRemoteServerPort.Text; }
            set { txtRemoteServerPort.Text = value; }
        }

        public string RemoteServerUserName
        {
            get { return txtUser.Text; }
            set { txtUser.Text = value; }
        }

        public string RemoteServerPassword
        {
            get { return txtPassword.Text; }
            set { txtPassword.Text = value; }
        }

        public bool RemoteServerUseDifferentCred
        {
            get { return chkUseDifferentCred.Checked; }
            set { chkUseDifferentCred.Checked = value; }
        }

        private void btnTestSettings_Click(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(this.RemoteServerAddress))
                {
                    throw new Exception("Remote server address can not be empty.");
                }

                if (string.IsNullOrEmpty(this.RemoteServerPort))
                {
                    throw new Exception("Remote server port can not be empty.");
                }

                ConnectionDetailsStruct con = new ConnectionDetailsStruct();

                con.Address = this.RemoteServerAddress;
                con.Port = int.Parse(this.RemoteServerPort);
                
                if (this.RemoteServerUseDifferentCred)
                {
                    con.UserName = this.RemoteServerUserName;
                    con.Password = this.RemoteServerPassword;
                }


                using (MainServiceWrapper svc = new MainServiceWrapper(con))
                {
                    string version = svc.ServiceProxy.GetServiceVersion();

                    MessageBox.Show("Settings are OK. Service version is " + version, "Test settings", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }


            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex, "SPVisualDev was unable to connect to the windows service 'SPVisualDevService' on server " + this.RemoteServerAddress + ". Make sure the service is running and that it runs as the SharePoint service account.", false);
            }

        }

    }
}
